unit uniConfig;

interface

uses
  uniDefine,
  SysUtils,
  IniFiles,
  Classes;

type
  AudioType =
    (
    AudioOpenAL,
    AudioSDL_Mixer,
    NumAudioTypes
    );

  { Config }

  Config = class(TObject)
  public
    //	int 	 m_screenW;
    m_screenW: Integer;
    //	int 	 m_screenH;
    m_screenH: Integer;
    //	float	 m_screenA;
    m_screenA: Single;
    //	float	 m_screenFOV;
    m_screenFOV: Single;
    //	float	 m_screenNear;
    m_screenNear: Single;
    //	float	 m_screenFar;
    m_screenFar: Single;
    //	bool	 m_full_screen;
    m_full_screen: Boolean;
    //	int 	 m_screenSize;
    m_screenSize: Integer;
    //	float	 m_screenBound[2];
    m_screenBound: array[0..1] of Single;
    //	float	 m_zTrans;
    m_zTrans: Single;
    //
    //	bool	 m_blend_enabled;
    m_blend_enabled: Boolean;
    //	bool	 m_tex_border;
    m_tex_border: Boolean;
    //	bool	 m_audio_enabled;
    m_audio_enabled: Boolean;
    //	bool	 m_swap_stereo;
    m_swap_stereo: Boolean;
    //	bool	 m_auto_speed;
    m_auto_speed: Boolean;
    //	bool	 m_show_fps;
    m_show_fps: Boolean;
    //	bool	 m_true_color;
    m_true_color: Boolean;
    //	bool	 m_use_playList;
    m_use_playList: Boolean;
    //	bool	 m_use_cdrom;
    m_use_cdrom: Boolean;
    //
    //	int 	 m_gfxLevel;
    m_gfxLevel: Integer;
    //	int 	 m_maxLevel;
    m_maxLevel: Integer;
    //	int		 m_cdromDevice;
    m_cdromDevice: Integer;
    //	int		 m_cdromCount;
    m_cdromCount: Integer;
    //
    //	float	 m_mouseSpeed;
    m_mouseSpeed: Single;
    //	float	 m_gameSkillBase;
    m_gameSkillBase: Single;
    //	float	 m_viewGamma;
    m_viewGamma: Single;
    //	float	 m_volSound;
    m_volSound: Single;
    //	float	 m_volMusic;
    m_volMusic: Single;
    //
    //	AudioType	m_audioType;
    m_audioType: AudioType;

    constructor Create;
    destructor Destroy; override;
    //	bool	readFile();
    function readFile: Boolean;
    //	bool	saveFile();
    function saveFile: Boolean;
    //
    //
    //	void	setScreenSize(int m);
    procedure setScreenSize(m: Integer);
    //
    //	int		screenSize()		{	return m_screenSize;	}
    function screenSize: Integer;
    //	int		screenW()			{	return m_screenW;		}
    function screenW: Integer;
    //	int		screenH()			{	return m_screenH;		}
    function screenH: Integer;
    //	float	screenA()			{	return m_screenA;		}
    function screenA: Single;
    //	float	screenFOV()			{	return m_screenFOV;		}
    function screenFOV: Single;
    //	float	screenNear()		{	return m_screenNear;	}
    function screenNear: Single;
    //	float	screenFar()			{	return m_screenFar;		}
    function screenFar: Single;
    //	float	screenBoundX()		{	return m_screenBound[0];}
    function screenBoundX: Single;
    //	float	screenBoundY()		{	return m_screenBound[1];}
    function screenBoundY: Single;
    //	float	zTrans()			{	return m_zTrans;		}
    function zTrans: Single;
    //
    //	bool	fullScreen()		{	return	m_full_screen;	}
    function fullScreen: Boolean;
    //	bool	blend()				{	return	m_blend_enabled;}
    function blend: Boolean;
    //	bool	texBorder()			{	return	m_tex_border;	}
    function texBorder: Boolean;
    //	bool	audioEnabled()		{	return	m_audio_enabled;}
    function audioEnabled: Boolean;
    //	bool	swapStereo()		{	return  m_swap_stereo;	}
    function swapStereo: Boolean;
    //	bool	autoSpeed()			{	return  m_auto_speed;	}
    function autoSpeed: Boolean;
    //	bool	showFPS()			{	return  m_show_fps;		}
    function showFPS: Boolean;
    //	bool	trueColor()			{	return  m_true_color;	}
    function trueColor: Boolean;
    //	bool	usePlayList()		{	return  m_use_playList;	}
    function usePlayList: Boolean;
    //	bool	useCDROM()			{	return  m_use_cdrom;		}
    function useCDROM: Boolean;
    //	void	setFullScreen(bool s)		{	m_full_screen = s;	}
    procedure setFullScreen(s: Boolean);
    //	void	setBlend(bool s)			{	m_blend_enabled = s;}
    procedure setBlend(s: Boolean);
    //	void	setTexBorder(bool s)		{	m_tex_border = s;	}
    procedure setTexBorder(s: Boolean);
    //	void	setAudio(bool s)			{	m_audio_enabled = s;}
    procedure setAudio(s: Boolean);
    //	void	setSwapStereo(bool s)		{	m_swap_stereo = s;	}
    procedure setSwapStereo(s: Boolean);
    //	void	setAutoSpeed(bool s)		{	m_auto_speed = s;	}
    procedure setAutoSpeed(s: Boolean);
    //	void	setShowFPS(bool s)			{	m_show_fps = s;		}
    procedure setShowFPS(s: Boolean);
    //	void	setTrueColor(bool s)		{	m_true_color = s;	}
    procedure setTrueColor(s: Boolean);
    //	void	setUsePlayList(bool s)		{	m_use_playList = s;	}
    procedure setUsePlayList(s: Boolean);
    //	void	setUseCDROM(bool s)			{	m_use_cdrom = s;	}
    procedure setUseCDROM(s: Boolean);
    //
    //	int		CDROMDevice()			{   return m_cdromDevice;	}
    function CDROMDevice: Integer;
    //	int		CDROMCount()			{   return m_cdromCount;	}
    function CDROMCount: Integer;
    //	void	setCDROMDevice(int i)	{	m_cdromDevice = i;		}
    procedure setCDROMDevice(i: Integer);
    //	void	setCDROMCount(int c)	{	m_cdromCount  = c;		}
    procedure setCDROMCount(c: Integer);
    //
    //	int 	gfxLevel()		{	return m_gfxLevel;	}
    function gfxLevel: Integer;
    //	int 	maxLevel()		{	return m_maxLevel;	}
    function maxLevel: Integer;
    //	void	setGfxLevel(int a)	{	m_gfxLevel = a; if(m_gfxLevel < 0) m_gfxLevel = 0; if(m_gfxLevel > 2) m_gfxLevel = 2; }
    procedure setGfxLevel(a: Integer);
    //	void	setMaxLevel(int a)	{	m_maxLevel = a; if(m_maxLevel > 10) m_maxLevel = 10;	}
    procedure setMaxLevel(a: Integer);
    //
    //	float	mouseSpeed()		{	return m_mouseSpeed;		}
    function mouseSpeed: Single;
    //	float	gameSkillBase()		{	return m_gameSkillBase;	}
    function gameSkillBase: Single;
    //	float	viewGamma()			{	return m_viewGamma;		}
    function viewGamma: Single;
    //	float	volSound()			{	return m_volSound;		}
    function volSound: Single;
    //	float	volMusic()			{	return m_volMusic;		}
    function volMusic: Single;
    //	void	setMouseSpeed(float f)		{	m_mouseSpeed = f;	if(m_mouseSpeed < 0.01) m_mouseSpeed = 0.01; if(m_mouseSpeed > 0.1) m_mouseSpeed = 0.1;	}
    procedure setMouseSpeed(f: Single);
    //	void	setGameSkillBase(float f)	{	m_gameSkillBase = f;	if(m_gameSkillBase > 0.9) m_gameSkillBase = 0.9; if(m_gameSkillBase < 0.2) m_gameSkillBase = 0.2;}
    procedure setGameSkillBase(f: Single);
    //	void	setViewGamma(float f)		{	m_viewGamma = f;		}
    procedure setViewGamma(f: Single);
    //	void	setVolSound(float f)		{	m_volSound = f;	if(m_volSound < 0.0) m_volSound = 0.0; if(m_volSound > 1.0) m_volSound = 1.0;	}
    procedure setVolSound(f: Single);
    //	void	setVolMusic(float f)		{	m_volMusic = f;	if(m_volMusic < 0.0) m_volMusic = 0.0; if(m_volMusic > 1.0) m_volMusic = 1.0;	}
    procedure setVolMusic(f: Single);
    //
    //	int		intSkill()	{ return (int)((m_gameSkillBase+0.05)*10.0); }
    function intSkill: Integer;
    //  AudioType	audioType()	{ return m_audioType; };
    function audioType: AudioType;
  end;


var
  m_instance: Config;

function init: Config;
function instance: Config;
procedure _destroy;


implementation


///**
// * create single Config object
// * @returns Config::m_instance
// */

function init: Config;
begin
  if m_instance = nil then
  begin
    m_instance := Config.Create;
  end
  else
  begin
    Writeln('WARNING: Config::init() has already been called.');
  end;
  Result := m_instance;
end;

///**
// * @returns Config::m_instance
// */

function instance: Config;
begin
  if m_instance = nil then
  begin
    Result := init;
  end
  else
  begin
    Result := m_instance;
  end;
end;

///**
// * deletes singleton instance and sets Config::m_instance to 0.
// */

procedure _destroy;
begin
  m_instance.Destroy;
  m_instance := nil;
end;

{ Config }

constructor Config.Create;
begin
  //-- setup defaults
  m_screenW := 800;
  m_screenH := 600;
  m_screenA := 1.3333333;
  m_screenFOV := 30.0;
  m_screenNear := 10.0;
  m_screenFar := 70.0;
  m_full_screen := false;
  m_screenSize := 2;
  m_screenBound[0] := 11.0;
  m_screenBound[1] := 9.0;
  m_zTrans := -56.5;
  m_blend_enabled := true;
  m_tex_border := true;
  m_audio_enabled := true;
  m_swap_stereo := false;
  m_show_fps := true;
  m_auto_speed := false;
  m_true_color := false;
  m_use_playList := false;
  m_use_cdrom := true;
  m_cdromDevice := 0;
  m_cdromCount := 1;
  m_maxLevel := 1;
  m_gfxLevel := 2;
  m_mouseSpeed := 0.03;
  m_gameSkillBase := 0.5;
  m_viewGamma := 1.1;
  m_volSound := 0.9;
  m_volMusic := 0.5;
  m_audioType := AudioSDL_Mixer;
  readFile;
end;

destructor Config.Destroy;
begin
  saveFile;
  inherited;
end;


function Config.audioEnabled: Boolean;
begin
  Result := m_audio_enabled;
end;

function Config.audioType: AudioType;
begin
  Result := m_audioType;
end;

function Config.autoSpeed: Boolean;
begin
  Result := m_auto_speed;
end;

function Config.blend: Boolean;
begin
  Result := m_blend_enabled;
end;

function Config.CDROMCount: Integer;
begin
  Result := m_cdromCount;
end;

function Config.CDROMDevice: Integer;
begin
  Result := m_cdromDevice;
end;

function Config.fullScreen: Boolean;
begin
  Result := m_full_screen;
end;

function Config.gameSkillBase: Single;
begin
  Result := m_gameSkillBase;
end;

function Config.gfxLevel: Integer;
begin
  Result := m_gfxLevel;
end;

function Config.intSkill: Integer;
begin
  { return (int)((m_gameSkillBase+0.05)*10.0); }
  Result := Round((m_gameSkillBase + 0.05) * 10.0);
end;

function Config.maxLevel: Integer;
begin
  Result := m_maxLevel;
end;

function Config.mouseSpeed: Single;
begin
  Result := m_mouseSpeed;
end;

function Config.readFile: Boolean;
var

  //int		i;
  i: Integer;
  //int		numLines;
  numLines: Integer;
  //bool	retVal = true;
  retVal: Boolean;
  //char	configFilename[256];
  configFilename: string;
  //FILE	*file;
  _file: TEXTFILE;
  //int		tmp;
  tmp: Integer;
  //const char *homeDir = getenv("HOME");
  homeDir: string;
  //char	configStrings[32][64];
  configString: array[0..63] of string;

  SetupIni: TIniFile;
begin
  Result := True;
  homeDir := './';
  configFilename := homeDir + CONFIG_FILE + '.ini';
  //alterPathForPlatform(configFilename);
  if FileExists(configFilename) then
  begin
    try
      SetupIni := TIniFile.Create(configFilename);
      m_screenSize := SetupIni.ReadInteger('CONFIG', 'screenSize', 2);
      m_mouseSpeed := SetupIni.ReadFloat('CONFIG', 'mouseSpeed', 0.03);
      m_gameSkillBase := SetupIni.ReadFloat('CONFIG', 'gameSkillBase', 0.05);
      m_gfxLevel := SetupIni.ReadInteger('CONFIG', 'gfxLevel', 2);
      m_volSound := SetupIni.ReadFloat('CONFIG', 'volSound', 0.9);
      m_volMusic := SetupIni.ReadFloat('CONFIG', 'volMusic', 0.5);
      m_full_screen := SetupIni.ReadBool('CONFIG', 'full_screen', False);
      m_true_color := SetupIni.ReadBool('CONFIG', 'true_color', False);
      m_swap_stereo := SetupIni.ReadBool('CONFIG', 'swap_stereo', False);
      m_auto_speed := SetupIni.ReadBool('CONFIG', 'auto_speed', False);
      m_show_fps := SetupIni.ReadBool('CONFIG', 'show_fps', False);
      m_use_playList := SetupIni.ReadBool('CONFIG', 'use_playList', False);
      m_use_cdrom := SetupIni.ReadBool('CONFIG', 'use_cdrom', True);
      m_audioType := uniConfig.AudioType(SetupIni.ReadInteger('CONFIG', 'use_cdrom', Integer(AudioSDL_Mixer)));
      m_maxLevel := SetupIni.ReadInteger('CONFIG', 'maxLevel', 1);
      m_viewGamma := SetupIni.ReadFloat('CONFIG', 'viewGamma', 1.1);
      m_cdromCount := SetupIni.ReadInteger('CONFIG', 'cdromCount', 1);
      m_cdromDevice := SetupIni.ReadInteger('CONFIG', 'cdromDevice', 0);
    finally
      SetupIni.Free;
    end;
  end
  else
  begin
    Writeln('WARNING: could not read config file (', configFilename, ')');
    Result := False;
  end;

end;

function Config.saveFile: Boolean;
var
  SetupIni: TIniFile;
  homeDir: string;
  configFilename: string;
begin
  Result := True;
  try
    homeDir := './';
    configFilename := homeDir + CONFIG_FILE + '.ini';
    SetupIni := TIniFile.Create(configFilename);
    SetupIni.WriteBool('CONFIG', 'use_playList', m_use_playList);
    SetupIni.WriteBool('CONFIG', 'use_cdrom', m_use_cdrom);
    SetupIni.WriteBool('CONFIG', 'full_screen', m_full_screen);
    SetupIni.WriteBool('CONFIG', 'true_color', m_true_color);
    SetupIni.WriteBool('CONFIG', 'swap_stereo', m_swap_stereo);
    SetupIni.WriteBool('CONFIG', 'auto_speed', m_auto_speed);
    SetupIni.WriteBool('CONFIG', 'show_fps', m_show_fps);
    SetupIni.WriteInteger('CONFIG', 'screenSize', m_screenSize);
    SetupIni.WriteInteger('CONFIG', 'gfxLevel', m_gfxLevel);
    SetupIni.WriteFloat('CONFIG', 'gameSkillBase', m_gameSkillBase);
    SetupIni.WriteFloat('CONFIG', 'mouseSpeed', m_mouseSpeed);
    SetupIni.WriteInteger('CONFIG', 'maxLevel', m_maxLevel);
    SetupIni.WriteFloat('CONFIG', 'volSound', m_volSound);
    SetupIni.WriteFloat('CONFIG', 'volMusic', m_volMusic);
    SetupIni.WriteFloat('CONFIG', 'viewGamma', m_viewGamma);
    SetupIni.WriteInteger('CONFIG', 'audioType', Integer(m_audioType));
    SetupIni.WriteInteger('CONFIG', 'cdromCount', m_cdromCount);
    SetupIni.WriteInteger('CONFIG', 'cdromDevice', m_cdromDevice);
    Writeln('wrote config file (', configFilename, ')');
  finally
    SetupIni.Free;
  end;
end;

function Config.screenA: Single;
begin
  Result := m_screenA;
end;

function Config.screenBoundX: Single;
begin
  Result := m_ScreenBound[0];
end;

function Config.screenBoundY: Single;
begin
  Result := m_ScreenBound[1];
end;

function Config.screenFar: Single;
begin
  Result := m_screenFar;
end;

function Config.screenFOV: Single;
begin
  Result := m_screenFOV;
end;

function Config.screenH: Integer;
begin
  Result := m_screenH;
end;

function Config.screenNear: Single;
begin
  Result := m_screenNear;
end;

function Config.screenSize: Integer;
begin
  Result := m_screenSize;
end;

function Config.screenW: Integer;
begin
  Result := m_screenW;
end;

procedure Config.setAudio(s: Boolean);
begin
  m_audio_enabled := s;
end;

procedure Config.setAutoSpeed(s: Boolean);
begin
  m_auto_speed := s;
end;

procedure Config.setBlend(s: Boolean);
begin
  m_blend_enabled := s;
end;

procedure Config.setCDROMCount(c: Integer);
begin
  m_cdromCount := c;
end;

procedure Config.setCDROMDevice(i: Integer);
begin
  m_cdromDevice := i;
end;

procedure Config.setFullScreen(s: Boolean);
begin
  m_full_screen := s;
end;

procedure Config.setGameSkillBase(f: Single);
begin
  m_gameSkillBase := f;
  if (m_gameSkillBase > 0.9) then m_gameSkillBase := 0.9;
  if (m_gameSkillBase < 0.2) then m_gameSkillBase := 0.2;
end;

procedure Config.setGfxLevel(a: Integer);
begin
  m_gfxLevel := a;
  if (m_gfxLevel < 0) then m_gfxLevel := 0;
  if (m_gfxLevel > 2) then m_gfxLevel := 2;
end;

procedure Config.setMaxLevel(a: Integer);
begin
  m_maxLevel := a;
  if (m_maxLevel > 10) then m_maxLevel := 10;
end;

procedure Config.setMouseSpeed(f: Single);
begin
  m_mouseSpeed := f;
  if (m_mouseSpeed < 0.01) then m_mouseSpeed := 0.01;
  if (m_mouseSpeed > 0.1) then m_mouseSpeed := 0.1;
end;

procedure Config.setScreenSize(m: Integer);
begin
  m_screenSize := m;
  if m_screenSize > MAX_SCREEN_SIZE then m_screenSize := MAX_SCREEN_SIZE;
  if m_screenSize < MIN_SCREEN_SIZE then m_screenSize := MIN_SCREEN_SIZE;
  case m_screenSize of
    0:
      begin
        m_screenW := 512;
        m_screenH := 384;
      end;
    1:
      begin
        m_screenW := 640;
        m_screenH := 480;
      end;
    2:
      begin
        m_screenW := 800;
        m_screenH := 600;
      end;
    3:
      begin
        m_screenW := 1024;
        m_screenH := 768;
      end;
    4:
      begin
        m_screenW := 1280;
        m_screenH := 960;
      end;
  else
    m_screenSize := 1;
    m_screenW := 640;
    m_screenH := 480;
  end;

  m_screenA := m_screenW / m_screenH;
end;

procedure Config.setShowFPS(s: Boolean);
begin
  m_show_fps := s;
end;

procedure Config.setSwapStereo(s: Boolean);
begin
  m_swap_stereo := s;
end;

procedure Config.setTexBorder(s: Boolean);
begin
  m_tex_border := s;
end;

procedure Config.setTrueColor(s: Boolean);
begin
  m_true_color := s;
end;

procedure Config.setUseCDROM(s: Boolean);
begin
  m_use_cdrom := s;
end;

procedure Config.setUsePlayList(s: Boolean);
begin
  m_use_playList := s;
end;

procedure Config.setViewGamma(f: Single);
begin
  m_viewGamma := f;
end;

procedure Config.setVolMusic(f: Single);
begin
  m_volMusic := f;
  if (m_volMusic < 0.0) then m_volMusic := 0.0;
  if (m_volMusic > 1.0) then m_volMusic := 1.0;
end;

procedure Config.setVolSound(f: Single);
begin
  m_volSound := f;
  if (m_volSound < 0.0) then m_volSound := 0.0;
  if (m_volSound > 1.0) then m_volSound := 1.0;
end;

function Config.showFPS: Boolean;
begin
  Result := m_show_fps;
end;

function Config.swapStereo: Boolean;
begin
  Result := m_swap_stereo;
end;

function Config.texBorder: Boolean;
begin
  Result := m_tex_border;
end;

function Config.trueColor: Boolean;
begin
  Result := m_true_color;
end;

function Config.useCDROM: Boolean;
begin
  Result := m_use_cdrom;
end;

function Config.usePlayList: Boolean;
begin
  Result := m_use_playList;
end;

function Config.viewGamma: Single;
begin
  Result := m_viewGamma;
end;

function Config.volMusic: Single;
begin
  Result := m_volMusic;
end;

function Config.volSound: Single;
begin
  Result := m_volSound;
end;

function Config.zTrans: Single;
begin
  Result := m_zTrans;
end;

end.

